package arina.sh.ethernetcontrol;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.Toast;

public class EthernetActivity extends Activity implements OnTouchListener{


	private static  int SUBNET_ID;

	private static  String PASSWORD ;

	private static  String USER_NAME ;

	private static String LOCAL_IP ;
	private static String DDNS;
	private static  int PORT;
	private NETWORK_STATUS mNETWORK_STATUS;

	private Handler handlerResponse100 ;
	//	private Handler handlerResponse150 ;
	//	private Handler handlerResponse200 ;

	String status_response;

	IntentFilter networkfilter;
	NetworkChangeReceiver networkstatus;


	Relay relay100;
	Relay relay150;

	Relay relay200;

	System_Device system;
	Boolean loopHandle=true;
	boolean checkLocal;



	int timepost;

	private boolean shouldRestartSocketListen;
	readStatusUDPHandler udpHandler;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_ethernet);


		networkstatus=new NetworkChangeReceiver();
		SUBNET_ID = 20;
		PASSWORD = "123456";
		USER_NAME = "smarttnh";
		PORT=4321;
		DDNS="115.77.44.141";//"liennguyen.dyndns.org";
		LOCAL_IP = "192.168.1.45";
		networkfilter=new IntentFilter();
		system=new System_Device(LOCAL_IP, PORT,DDNS, USER_NAME, PASSWORD, SUBNET_ID) ;

		relay100=new Relay(system, 250, 12);
		relay150=new Relay(system, 150, 12);
		relay200=new Relay(system, 200, 12);

		shouldRestartSocketListen=true;
		startListenForUDPBroadcast();

		ImageView bg=(ImageView)findViewById(R.id.bg_image);
		bg.setOnTouchListener(new OnSwipeTouchListener() {
			@Override
			public void onSwipeTop() {
				Toast.makeText(getApplicationContext(), "top", Toast.LENGTH_SHORT).show();
			}
			@Override
			public void onSwipeRight() {
				Toast.makeText(getApplicationContext(), "right", Toast.LENGTH_SHORT).show();
			}
			@Override
			public void onSwipeLeft() {
				loopHandle=false;
				Intent i = new Intent(EthernetActivity.this,tang_tret_activity.class);
				Bundle bundle=new Bundle();

				bundle.putParcelable("system", system);
				bundle.putInt("network", mNETWORK_STATUS.ordinal());
				bundle.putInt("timepost", timepost);
				i.putExtras(bundle);

				startActivity(i);
				finish();
			}
			@Override
			public void onSwipeBottom() {
				Toast.makeText(getApplicationContext(), "bottom", Toast.LENGTH_SHORT).show();
			}
		});

		//relay100
		relay100.ArrButton[0]=(myToggleButton)findViewById(R.id.toggle_ac_thieunhi1);

		relay100.ArrButton[1]=(myToggleButton)findViewById(R.id.toggle_ac_thieunhi2);

		relay100.ArrButton[2]=(myToggleButton)findViewById(R.id.toggle_aunhi);

		relay100.ArrButton[3]=(myToggleButton)findViewById(R.id.toggle_den);

		assignListener(relay100);

		//relay150
		relay150.ArrButton[0]=(myToggleButton)findViewById(R.id.toggle_ac_bentrai1);

		relay150.ArrButton[1]=(myToggleButton)findViewById(R.id.toggle_ac_bentrai2);

		relay150.ArrButton[2]=(myToggleButton)findViewById(R.id.toggle_ac_benphai1);

		relay150.ArrButton[3]=(myToggleButton)findViewById(R.id.toggle_ac_benphai2);
		relay150.ArrButton[4]=(myToggleButton)findViewById(R.id.toggle_ac_cuoiphong);

		assignListener(relay150);

		//relay200
		relay200.ArrButton[0]=(myToggleButton)findViewById(R.id.toggle_ac_tonghoi);

		relay200.ArrButton[1]=(myToggleButton)findViewById(R.id.toggle_ac_vpms);

		relay200.ArrButton[2]=(myToggleButton)findViewById(R.id.toggle_ac_phongnghi2);
		assignListener(relay200);

		Relay[] arrRelay=new Relay[2];
		arrRelay[0]=relay100;
		arrRelay[1]=relay150;
		//arrRelay[2]=relay200;

		handlerResponse100=new Handler();
		//		handlerResponse150=new Handler();
		//		handlerResponse200=new Handler();

		Handler[] arrHandler=new Handler[1];
		arrHandler[0]=handlerResponse100;
		//		arrHandler[1]=handlerResponse150;
		//		arrHandler[2]=handlerResponse200;

		udpHandler=new readStatusUDPHandler();
		udpHandler.sendEmptyMessage(readStatusUDPHandler.relay1);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		udpHandler.sendEmptyMessage(readStatusUDPHandler.relay2);

		//		int timeStart=0;
		//		final Handler tempHandler=arrHandler[1];
		//		for (int i=0;i<arrRelay.length;i++) {
		//			final Relay tempRelay=arrRelay[i];
		//			
		//			Runnable iRun=new Runnable() {
		//				
		//				@Override
		//				public void run() {
		//					// TODO Auto-generated method
		//					if(mNETWORK_STATUS!=NETWORK_STATUS.NOT_CONNECTED)
		//					{
		//						
		//						//tempRelay.readStatus(mNETWORK_STATUS);
		//						tempRelay.readStatusUDP(1, NETWORK_STATUS.LOCAL);
		////						handleUIwithResponse handleUI=new handleUIwithResponse();
		////						handleUI.execute(new Relay[]{tempRelay});
		////						
		//						if(loopHandle)
		//						{
		//							tempHandler.postDelayed(this, timepost);
		//							
		//						}
		//					}
		//					else
		//						Toast.makeText(getApplicationContext(), mNETWORK_STATUS.toString(), Toast.LENGTH_SHORT).show();
		//				}
		//			};
		//			tempHandler.postDelayed(iRun, timeStart);
		//			timeStart+=500;
		//		}


	}

	public static class readStatusUDPHandler extends Handler{
		public static final int relay1=1;
		public static final int relay2=2;

		@Override
		public void handleMessage(Message msg){

			switch(msg.what){
			case relay1:
				Thread td1=new Thread(){
					@Override
					public void run(){
						helperClass.makeDataToSend(COMMAND_TYPE.READ_STATUS, SUBNET_ID, 100, 1, 0, USER_NAME, PASSWORD, LOCAL_IP, PORT);
					}
				};
				td1.start();

				sendEmptyMessageDelayed(relay1,4000);
				break;
			case relay2:
				Thread td2=new Thread(){
					@Override
					public void run(){
						helperClass.makeDataToSend(COMMAND_TYPE.READ_STATUS, SUBNET_ID, 150, 1, 0, USER_NAME, PASSWORD, LOCAL_IP, PORT);
					}
				};
				td2.start();
				sendEmptyMessageDelayed(relay2,4000);
				break;
				//		default:
				//			removeMessages(relay1);
				//			removeMessages(relay2);
				//			break;

			}
		}
	}


	private void assignListener(final Relay relay) {
		for(int i=0;i<relay.ArrButton.length;i++)
		{
			if(relay.ArrButton[i]!=null)
			{
				final myToggleButton currImageButton= relay.ArrButton[i];
				final int index=i;
				currImageButton.setOnClickListener(new View.OnClickListener() {

					@Override
					public void onClick(View v) {
						// TODO Auto-generated method stub
						//sendUDPinBackground sendUDP=new	sendUDPinBackground();
						if(currImageButton.isChecked()==false)
						{
							//sendUDP.execute(relay,index+1,true);
							relay.On(index+1,mNETWORK_STATUS);


						}
						else
						{
							//sendUDP.execute(relay,index+1,false);
							relay.Off(index+1,mNETWORK_STATUS);

						}
						//						try {
						//							Thread.sleep(100);
						//						} catch (InterruptedException e) {
						//							// TODO Auto-generated catch block
						//							e.printStackTrace();
						//						}
						//						Thread td=new Thread()
						//						{
						//							@Override
						//							public void  run() {
						//								relay.readStatusUDP(1, NETWORK_STATUS.LOCAL);
						//							}
						//						};
						//						td.start();
					}
				});	

			}
		}
	}
	//	private class sendUDPinBackground extends AsyncTask<Object, Void, Void>
	//	{
	//
	//		@Override
	//		protected Void doInBackground(Object... params) {
	//			Relay relay=(Relay)params[0];
	//			int channel=(Integer)params[1];
	//			Boolean isON=(Boolean)params[2];
	//			if(isON)
	//			{
	//				relay.On(channel, mNETWORK_STATUS);
	//				return null;
	//			}
	//			relay.Off(channel, mNETWORK_STATUS);
	//			return null;
	//			
	//		}
	//		
	//	}
	//	private class handleUIwithResponse extends AsyncTask<Relay, Void, String>{
	//		
	//		@Override
	//		protected String doInBackground(Relay...relay){
	//			if(relay[0].Response!=null)
	//			{
	//				String strResponse=relay[0].getID()+relay[0].Response;
	//				
	//				return strResponse;
	//
	//			}
	//			return null;
	//		}
	//			@Override
	//		    protected void onPostExecute(String result) {
	//				if(result!=null)
	//				{
	//					
	//					String strID=result.substring(0, 3);
	//					result=result.substring(3);
	//					int iID= Integer.parseInt(strID);
	//					switch (iID) {
	//					case 100:
	//						helperClass.updateUI(result.toCharArray(), relay100.ArrButton);
	//						break;
	//					case 150:
	//						helperClass.updateUI(result.toCharArray(), relay150.ArrButton);
	//						break;
	//					
	//						
	//					default:
	//						break;
	//					}
	//					
	//				}
	//		    }	
	//		
	//	}

	//	private Boolean isLocal(final String strURL) 
	//	{
	//		
	//		Thread td=new Thread(){
	//			@Override
	//				
	//				public void run() {
	//					
	//					try {
	//						HttpURLConnection Client = (HttpURLConnection)(new URL(strURL).openConnection());
	//						Client.setConnectTimeout(1500);
	//						Client.setReadTimeout(1300);
	//						Client.connect();
	//						int responseCode=Client.getResponseCode();
	//						if(responseCode!=200)
	//						{
	//							checkLocal= false;
	//							return;
	//						}
	//						else
	//						{
	//							InputStream is=Client.getInputStream();
	//							String localResponse=helperClass.readIt(is, 10);
	//							String header="SMARTHOUSE";
	//							char[] arrHeader=header.toCharArray();
	//							char[] arrLocalResponse=localResponse.trim().toCharArray();
	//							if(helperClass.compareByteArray(arrHeader, arrLocalResponse))
	//							{
	//								checkLocal= true;
	//								return;
	//							}
	//							
	//						}
	//						     
	//						checkLocal= false;
	//					} catch (IOException e) {
	//						// TODO Auto-generated catch block
	//						checkLocal= false;
	//					}
	//					
	//				}
	//			
	//		};
	//		td.start();
	//		return checkLocal;
	//		
	//	}




	@Override
	protected void onResume(){
		super.onResume();

		networkfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

		registerReceiver(networkstatus, networkfilter);

		loopHandle=true;
		shouldRestartSocketListen = true;
		udpHandler.sendEmptyMessage(readStatusUDPHandler.relay1);
		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		udpHandler.sendEmptyMessage(readStatusUDPHandler.relay2);
	}


	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		unregisterReceiver(networkstatus);
		loopHandle=false;
		shouldRestartSocketListen = false;

		udpHandler.removeMessages(readStatusUDPHandler.relay1);
		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		udpHandler.removeMessages(readStatusUDPHandler.relay2);
	}

	private class NetworkChangeReceiver extends BroadcastReceiver{


		private static final String MyMAC = "48:f8:b3:32:71:80";

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			getNetworkState(context);
		}

		public void getNetworkState(Context context) {
			int status = NetworkUtil.getConnectivityStatus(context);

			loopHandle=true;

			if(status==2)//mobile
			{
				mNETWORK_STATUS=NETWORK_STATUS.EXTERNAL;
				timepost=3500;	
			}
			else if(status==1)//wifi
			{

				//Boolean checkStatus_Local=isLocal("http://"+LOCAL_IP+":"+PORT+"/SMARTHOUSE/"+USER_NAME+"/"+PASSWORD+"/0033/14/fa");
				char[] macadd=getMacId();

				char[] arrMyMAC=MyMAC.toCharArray();
				if(helperClass.compareByteArray(macadd, arrMyMAC))
				{
					mNETWORK_STATUS=NETWORK_STATUS.LOCAL;		
					timepost=1500;
				}
				else
				{
					mNETWORK_STATUS=NETWORK_STATUS.EXTERNAL;
					timepost=3500;
				}

				//				if(hasActiveInternetConnection(getApplicationContext()))
				//					{
				//						mNETWORK_STATUS=NETWORK_STATUS.INTERNET;
				//					}
			}
			else if(status==0)//not connected
			{
				mNETWORK_STATUS=NETWORK_STATUS.NOT_CONNECTED;
				loopHandle=false;
			}
			Toast.makeText(getApplicationContext(), mNETWORK_STATUS.toString(), Toast.LENGTH_SHORT).show();
		}

	}
	public char[] getMacId() {

		WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		WifiInfo wifiInfo = wifiManager.getConnectionInfo();
		return wifiInfo.getBSSID().toCharArray();
	}
	public static String getCurrentSsid(Context context) {
		String ssid = null;
		ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		if (networkInfo.isConnected()) {
			final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
			final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
			if (connectionInfo != null) {
				ssid = connectionInfo.getSSID();
			}
		}
		return ssid;
	}

	InetAddress getBroadcastAddress() throws IOException {
		WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
		DhcpInfo dhcp = wifi.getDhcpInfo();
		// handle null somehow

		int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
		byte[] quads = new byte[4];
		for (int k = 0; k < 4; k++)
			quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
		return InetAddress.getByAddress(quads);
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.ethernet, menu);
		return true;
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		return false;
	}


	Thread UDPBroadcastThread;
	DatagramSocket datasocket;
	Handler handlerUIThread=new Handler();
	void startListenForUDPBroadcast() {
		UDPBroadcastThread = new Thread(new Runnable() {
			@Override
			public void run() {
				//				byte[] result=new byte[30];
				try {
					InetAddress broadcastIP = getBroadcastAddress();//InetAddress.getByName("192.168.1.255"); //172.16.238.42 //192.168.1.255
					Integer port = 8000;
					while (shouldRestartSocketListen) {

						Message msg=handler.obtainMessage();
						Bundle b=new Bundle();

						byte[] recvBuf = new byte[30];


						if (datasocket == null || datasocket.isClosed()) {
							try {

								datasocket = new DatagramSocket(port, broadcastIP);
								datasocket.setBroadcast(true);


							} catch (SocketException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							} 

						}
						DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
						//socket.setSoTimeout(5000);
						Log.i("open", "open");
						try {
							datasocket.receive(packet);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						byte[] udpresponse=null;
						byte[] headerUDPResponse=helperClass.hexStringToByteArray("534D415254484F5553450034");
						if(helperClass.compareByteArray(packet.getData(),headerUDPResponse))
						{
							udpresponse=packet.getData();
							switch(udpresponse[13])
							{
							case 100:
								isChangeResponse(msg, b, udpresponse,relay100);
								break;
							case (byte) 150:
								isChangeResponse(msg, b, udpresponse,relay150);
							break;
							}
						}




					}
					//if (!shouldListenForUDPBroadcast) throw new ThreadDeath();
				} catch (Exception e) {
					Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
				}
			}
			private void isChangeResponse(Message msg, Bundle b,
					byte[] udpresponse,Relay relay) {
				if (!helperClass.compareByteArray(udpresponse,relay.lastudpResponse)) {
					relay.lastudpResponse=udpresponse;
					b.putByteArray("udpresponse", udpresponse);
					msg.setData(b);
					handler.sendMessage(msg);
				}
			}
			@SuppressLint("HandlerLeak")
			private final Handler handler=new Handler(){

				@Override
				public void handleMessage(Message msg) {
					// TODO Auto-generated method stub
					super.handleMessage(msg);
					byte[] response=msg.getData().getByteArray("udpresponse");
					if(response!=null)
					{
						switch (response[13]) {
						case 100:
							helperClass.updateUIUDP(response, relay100.ArrButton);
							break;
						case (byte) 150:
							helperClass.updateUIUDP(response, relay150.ArrButton);
						break;

						default:
							break;
						}
					}
				}

			};
		});
		UDPBroadcastThread.start();
	}

}
